package com.woniu.service.Impl;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.woniu.dao.CreditUserDao;
import com.woniu.entity.CreLogin;
import com.woniu.entity.CreUser;
import com.woniu.service.CreditUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


@Service
public class CreditUserServiceImpl implements CreditUserService {

    private static final Logger log = LoggerFactory.getLogger(CreditUserServiceImpl.class);


    @Resource
    private CreditUserDao creditUserDao;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private RedisCache redisCache;

    @Resource
    private SysUserMapper userMapper;


    @Override
    @Transactional
    public String register(CreLogin creLogin) {
        String msg = "", username = creLogin.getUsername(), password = creLogin.getPassword(), phonenumber = creLogin.getPhonenumber();

//        手机号正则判断
        String isPhone = "^1[3|4|5|6|7|8|9][0-9]\\d{8}$";
        Pattern p = Pattern.compile(isPhone);
        Matcher m = p.matcher(phonenumber);
        boolean captchaEnabled = configService.selectCaptchaEnabled();
        // 验证码开关
        if (captchaEnabled) {
            validateCaptcha(username, creLogin.getCode(), creLogin.getUuid());
        }
        if (StringUtils.isEmpty(username)) {
            msg = "用户名不能为空";
        } else if (StringUtils.isEmpty(password)) {
            msg = "用户密码不能为空";
        } else if (StringUtils.isEmpty(phonenumber)) {
            msg = "用户手机号不能为空";
        } else if (!m.matches()) {
            msg = "请输入正确的手机号码";
        } else if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
            msg = "账户长度必须在2到20个字符之间";
        } else if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
            msg = "密码长度必须在5到20个字符之间";
        } else if (UserConstants.NOT_UNIQUE.equals(creditUserDao.checkUserNameUnique(username) > 0 ? UserConstants.NOT_UNIQUE : UserConstants.UNIQUE)) {
            msg = "保存用户'" + username + "'失败，注册账号已存在";
        } else if (UserConstants.NOT_UNIQUE.equals(creditUserDao.checkPhoneNumberUnique(phonenumber) > 0 ? UserConstants.NOT_UNIQUE : UserConstants.UNIQUE)) {
            msg = "保存用户'" + username + "'失败，注册手机号已存在";
        } else {
            CreLogin creLogin1 = new CreLogin();
            creLogin1.setUserName(username);
            creLogin1.setNickName(username);
            creLogin1.setPhonenumber(phonenumber);
            creLogin1.setPassword(SecurityUtils.encryptPassword(creLogin.getPassword()));
            boolean regFlag = creditUserDao.registerUser(creLogin1) > 0;
            if (!regFlag) {
                msg = "注册失败,请联系系统管理人员";
            } else {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER,
                        MessageUtils.message("user.register.success")));
                //根据用户名查询对应ID
                long userIdByName = creditUserDao.findUserIdByName(username);
                //更新用户角色，默认为用户，roleId为100
                creditUserDao.insertRoleId(userIdByName, 100L);
                //角色详情表新增用户
                CreUser creUser = new CreUser();
                creUser.setUserId(userIdByName);
                creUser.setUserPhone(phonenumber);
                creditUserDao.insertUserDetail(creUser);
            }
        }
        return msg;
    }

    /**
     * 根据条件分页查询用户列表
     * author：李敬
     *
     * @return 用户信息集合信息
     */
    @Override
    public List<CreUser> selectUserList(CreUser user) {
        return creditUserDao.selectCreUserList(user);
    }

    @Override
    public void checkUserAllowed(SysUser user) {
        if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) {
            throw new ServiceException("不允许操作超级管理员用户");
        }
    }

    @Override
    public void checkUserDataScope(Long userId) {
        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
            CreUser user = new CreUser();
            user.setUserId(userId);
            List<CreUser> users = SpringUtils.getAopProxy(this).selectUserList(user);
            if (StringUtils.isEmpty(users)) {
                throw new ServiceException("没有权限访问用户数据！");
            }
        }
    }

    @Override
    public String checkPhoneUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
        SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber());
        if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public String checkEmailUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
        SysUser info = userMapper.checkEmailUnique(user.getEmail());
        if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }


    //提交按钮的时候更改用户
    @Override
    public int updateUser(CreUser user) {
        Long userId = user.getUserId();
        return creditUserDao.updateCreUser(user);
    }


    @Override
    public CreUser selectUserDetById(Long userId) {
        return creditUserDao.selectUserDetById(userId);
    }

    @Override
    public String checkIdentityCardUnique(CreUser user) {
        int info = creditUserDao.checkIdentityCardUnique(user.getIdentityCard(), user.getUserId());
        if (info > 0) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public String checkBankCardUnique(CreUser user) {
        int info = creditUserDao.checkBankCardUnique(user.getBankCard(), user.getUserId());
        if (info > 0) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public String checkHouseCertificateUnique(CreUser user) {
        int info = creditUserDao.checkHouseCertificateUnique(user.getHouseCertificate(), user.getUserId());
        if (info > 0) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 更新用户详情
     *
     * @param user
     * @return
     */
    @Override
    public int updateUserDetailProfile(CreUser user) {
        return creditUserDao.updateCreUser(user);
    }

    /**
     * 根据id查询用户
     *
     * @param id
     * @return
     */
    @Override
    public CreUser findUserById(int id) {
        return creditUserDao.findUserById(id);
    }

    @Override
    public List<CreUser> selectLoanUser() {
        return creditUserDao.selectLoanUser();
    }

    @Override
    public List<CreUser> selectLoansUser() {
        return creditUserDao.selectLoansUser();
    }

    @Override
    public List<CreUser> selectOutUser() {
        return creditUserDao.selectOutUser();
    }

    @Override
    public List<CreUser> selectOutsUser() {
        return creditUserDao.selectOutsUser();
    }

    @Override
    public SysUser findSysUserById(int id) {
        return creditUserDao.findSysUserById(id);
    }


    /**
     * 校验验证码
     *
     * @param username 用户名
     * @param code     验证码
     * @param uuid     唯一标识
     * @return 结果
     */
    public void validateCaptcha(String username, String code, String uuid) {
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);
        if (captcha == null) {
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha)) {
            throw new CaptchaException();
        }
    }
}